/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
/* vi: set expandtab shiftwidth=4 tabstop=4: */

#include <stdint.h>

/** \brief old hash by FNV
 * http://www.isthe.com/chongo/tech/comp/fnv/
 *
 * License: Public domain?
 */
class FNVHash32 {
 public:

    const char* name() const
    {
        return "FNVHash";
    }

    /** \brief alogirthm simplified for 32-bit int.
     *
     */
    uint32_t hash32(uint32_t key) const
    {
        uint8_t* bytes = (uint8_t*)(&key);
        uint32_t hash = 2166136261U;
        hash = (16777619U * hash) ^ bytes[0];
        hash = (16777619U * hash) ^ bytes[1];
        hash = (16777619U * hash) ^ bytes[2];
        hash = (16777619U * hash) ^ bytes[3];
        return hash;
    }

    uint64_t hash64(uint64_t key) const
    {
        uint8_t* bytes = (uint8_t*)(&key);
        uint32_t hash = 2166136261U;
        hash = (16777619U * hash) ^ bytes[0];
        hash = (16777619U * hash) ^ bytes[1];
        hash = (16777619U * hash) ^ bytes[2];
        hash = (16777619U * hash) ^ bytes[3];
        hash = (16777619U * hash) ^ bytes[4];
        hash = (16777619U * hash) ^ bytes[5];
        hash = (16777619U * hash) ^ bytes[6];
        hash = (16777619U * hash) ^ bytes[7];
        return hash;
    }

    uint32_t hashStr(const char* data, int len) const
    {
        uint32_t hash = 2166136261U;
        for (int32_t i=0; i < len; i++) {
            hash = (16777619U * hash) ^ (uint8_t)(data[i]);
        }
        return hash;
    }

};
